package com.study.basetype.util;

import java.time.*;
import java.time.format.DateTimeFormatter;
import java.time.format.FormatStyle;

/**
 * @author flwu
 * @date 2020/3/18 2:33 PM
 * @MOTTO 保持空杯和敬畏
 */
public class DateUtil {

    //时间元素
    public static final String YEAR = "year";
    public static final String MONTH = "month";
    public static final String WEEK = "week";
    public static final String DAY = "day";
    public static final String HOUR = "hour";
    public static final String MINUTE = "minute";
    public static final String SECOND = "second";

    //星期元素
    public static final String MONDAY = "MONDAY";
    public static final String TUESDAY = "TUESDAY";
    public static final String WEDNESDAY = "WEDNESDAY";
    public static final String THURSDAY = "THURSDAY";
    public static final String FRIDAY = "FRIDAY";
    public static final String SATURDAY = "SATURDAY";
    public static final String SUNDAY = "SUNDAY";

    /**
     * 时间格式
     */
    public static final DateTimeFormatter YYYY_MM_DD_EN = DateTimeFormatter.ofPattern("yyyy-MM-dd");
    public static final DateTimeFormatter YYYY_MM_DD_HH_EN = DateTimeFormatter.ofPattern("yyyy-MM-dd HH");
    public static final DateTimeFormatter YYYY_MM_DD_HH_MM_EN = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm");
    public static final DateTimeFormatter YYYY_MM_DD_HH_MM_SS_EN = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
    public static final DateTimeFormatter HH_MM_SS_EN = DateTimeFormatter.ofPattern("HH:mm:ss");
    public static final DateTimeFormatter HH_MM_EN = DateTimeFormatter.ofPattern("HH:mm");

    public static final DateTimeFormatter YYYY_MM_DD_CN = DateTimeFormatter.ofPattern("yyyy年MM月dd日");
    public static final DateTimeFormatter YYYY_MM_DD_HH_CN = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时");
    public static final DateTimeFormatter YYYY_MM_DD_HH_MM_CN = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分");
    public static final DateTimeFormatter YYYY_MM_DD_HH_MM_SS_CN = DateTimeFormatter.ofPattern("yyyy年MM月dd日HH时mm分ss秒");
    public static final DateTimeFormatter HH_MM_CN = DateTimeFormatter.ofPattern("HH时mm分");
    public static final DateTimeFormatter HH_MM_SS_CN = DateTimeFormatter.ofPattern("HH时mm分ss秒");

    /**
     * 本地时间显示
     */
    public static final DateTimeFormatter SHOTDATE = DateTimeFormatter.ofLocalizedDate(FormatStyle.SHORT);
    public static final DateTimeFormatter FULLDATE = DateTimeFormatter.ofLocalizedDate(FormatStyle.FULL);
    public static final DateTimeFormatter LONGDATE = DateTimeFormatter.ofLocalizedDate(FormatStyle.LONG);
    public static final DateTimeFormatter MEDIUMDATE = DateTimeFormatter.ofLocalizedDate(FormatStyle.MEDIUM);


    /**
     * 日期字符串转为时间戳,格式要求比较严格，必须为：YYYY_MM_DD_HH_MM_SS
     * @return
     */
    public static Long dateToLong(String date) {
        LocalDateTime parse = LocalDateTime.parse(date, DateUtil.YYYY_MM_DD_HH_MM_SS_EN);
        return LocalDateTime.from(parse).atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    /**
     * 将时间戳转为字符串
     */
    public static String longToDate(Long time, DateTimeFormatter dateTimeFormatter) {
        return LocalDateTime.ofInstant(Instant.ofEpochMilli(time), ZoneId.systemDefault()).format(dateTimeFormatter);
    }

    /**
     * 获取当前时间戳-毫秒
     * @return
     */
    public static Long getCurrentTimeMilli() {
        return LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant().toEpochMilli();
    }

    /**
     * 获取当前时间戳-秒
     * @return
     */
    public static Long getCurrentTimeSecond() {
        return Instant.now().getEpochSecond();
    }

    /**
     * 获取当前时间，默认格式为：2019-08-08 12:12:12
     * @return
     */
    public static String getNowDateTime() {
        return LocalDateTime.now().format(YYYY_MM_DD_HH_MM_SS_EN);
    }

    /**
     * 获取当前时间，默认格式为：2019-09-09
     * @return
     */
    public static String getNowDate() {
        return LocalDateTime.now().format(YYYY_MM_DD_EN);
    }

    /**
     * 获取当前时间，默认格式为：12:12:12
     * @return
     */
    public static String getNowTime(){
        return LocalDateTime.now().format(HH_MM_SS_EN);
    }

    /**
     * 根据格式获取当前时间
     * @param dateTimeFormatter
     * @return
     */
    public static String getNowDateTime(DateTimeFormatter dateTimeFormatter) {
        return LocalDateTime.now().format(dateTimeFormatter);
    }

    /**
     * 获取本地时间:
     * @param dateTimeFormatter
     * SHOTDATE : 19-3-30
     * FULLDATE : 2020年3月18日 星期三
     * LONGDATE : 2019年3月30日
     * MEDIUMDATE : 2019-3-30
     * @return
     */
    public static String getNowLocalDateTime(DateTimeFormatter dateTimeFormatter) {
        return LocalDateTime.now().format(dateTimeFormatter);
    }

    /**
     * 获取当前日期的节点时间
     * @param node
     * @return
     */
    public static Integer getNodeTime(String node) {
        LocalDateTime localDateTime = LocalDateTime.now();
        Integer resultCode = null;
        switch(node) {
            case YEAR:
                resultCode = localDateTime.getYear();
                break;
            case MONTH:
                resultCode = localDateTime.getMonthValue();
                break;
            case WEEK:
                resultCode = getWeek(String.valueOf(localDateTime.getDayOfWeek()));
                break;
            case DAY:
                resultCode = localDateTime.getDayOfMonth();
                break;
            case HOUR:
                resultCode = localDateTime.getHour();
                break;
            case MINUTE:
                resultCode = localDateTime.getMinute();
                break;
            case SECOND:
                resultCode = localDateTime.getSecond();
                break;
            default:
                resultCode = localDateTime.getDayOfYear();
                break;
        }
        return resultCode;
    }


    /**
     * 根据日期英文换取周几
     * @param week
     * @return
     */
    public static Integer getWeek(String week) {
        if (week.equals(MONDAY)) {
            return 1;
        } else if (week.equals(TUESDAY)) {
            return 2;
        } else if (week.equals(WEDNESDAY)) {
            return 3;
        } else if (week.equals(THURSDAY)) {
            return 4;
        } else if (week.equals(FRIDAY)) {
            return 5;
        } else if (week.equals(SATURDAY)) {
            return 6;
        } else if (week.equals(SUNDAY)) {
            return 7;
        } else {
            return -1;
        }
    }

    /**
     * 根据格式和节点获取之前或之后制定时间的时间
     * @param dateTimeFormatter
     * @param node
     * @param num
     * @return
     */
    public static String getBeforeORAfterDateTime(DateTimeFormatter dateTimeFormatter, String node, Long num) {
        LocalDateTime now = LocalDateTime.now();
        if (YEAR.equals(node)) {
            return now.plusYears(num).format(dateTimeFormatter);
        } else if (MONTH.equals(node)) {
            return now.plusMonths(num).format(dateTimeFormatter);
        } else if (WEEK.equals(node)) {
            return now.plusWeeks(num).format(dateTimeFormatter);
        } else if (DAY.equals(node)) {
            return now.plusDays(num).format(dateTimeFormatter);
        } else if (HOUR.equals(node)) {
            return now.plusHours(num).format(dateTimeFormatter);
        } else if (MINUTE.equals(node)) {
            return now.plusMinutes(num).format(dateTimeFormatter);
        } else if (SECOND.equals(node)) {
            return now.plusSeconds(num).format(dateTimeFormatter);
        } else {
            return "Node is not exist";
        }
    }

    /**
     * 判断是否是闰年
     * @param date
     * @return
     */
    public static boolean isLeapYear(String date) {
        return LocalDate.parse(date.trim()).isLeapYear();
    }

    /**
     * 计算两个日期间隔多少 天、月、年
     * @param fromDate
     * @param toDate
     * @param node
     * @return
     */
    public static int intervalCount(String fromDate, String toDate, String node) {
        if (DAY.equals(node)) {
            return Period.between(LocalDate.parse(fromDate.trim()), LocalDate.parse(toDate.trim())).getDays();
        } else if (MONTH.equals(node)) {
            return Period.between(LocalDate.parse(fromDate.trim()), LocalDate.parse(toDate.trim())).getMonths();
        } else if (YEAR.equals(node)) {
            return Period.between(LocalDate.parse(fromDate.trim()), LocalDate.parse(toDate.trim())).getYears();
        } else {
            return 0;
        }
    }

}
